home *** CD-ROM | disk | FTP | other *** search
/ MacHack 2000 / MacHack 2000.toast / pc / The Hacks / Softshoe / Lisa's Mac Parts / Views / Tiled Views / RuledFourSquareTiling.cp < prev    next >
Text File  |  2000-06-23  |  8KB  |  239 lines

  1. // RuledFourSquareTiling.cp
  2.  
  3. #ifndef RuledFourSquareTiling_h
  4. #include "RuledFourSquareTiling.h"
  5. #endif
  6. #ifndef MinMax_h
  7. #include "MinMax.h"
  8. #endif
  9. #ifndef ViewCell_h
  10. #include "ViewCell.h"
  11. #endif
  12.  
  13. RuledFourSquareTiling::RuledFourSquareTiling()
  14.   {
  15.     Add( topLeft, afterEnd );
  16.     Add( topRight, afterEnd );
  17.     Add( bottomLeft, afterEnd );
  18.     Add( bottomRight, afterEnd );
  19.     Add( horizontalLine, afterEnd );
  20.     Add( upperVerticalLine, afterEnd );
  21.     Add( lowerVerticalLine, afterEnd );
  22.     
  23.     horizontalLine.SetContent( ViewCell::Black() );
  24.     upperVerticalLine.SetContent( ViewCell::Black() );
  25.     lowerVerticalLine.SetContent( ViewCell::Black() );
  26.   }
  27.  
  28. int32 RuledFourSquareTiling::TileSum( int32 a, int32 b )
  29.   {
  30.     return ( a < maxint32 - 1 - b )
  31.              ? a + 1 + b
  32.              : maxint32;
  33.   }
  34.  
  35. int32 RuledFourSquareTiling::HorizontalSplitPosition() const
  36.   {
  37.     int32 minimumLeft = Max( topLeft.Sizer().MinimumWidth(),
  38.                                      bottomLeft.Sizer().MinimumWidth() );
  39.     
  40.     if ( minimumLeft >= PaneSize().h )
  41.         return PaneSize().h;
  42.     
  43.     int32 minimumRight = Max( topRight.Sizer().MinimumWidth(),
  44.                                       bottomRight.Sizer().MinimumWidth() );
  45.  
  46.     if ( minimumRight >= PaneSize().h - 1 - minimumLeft )
  47.         return minimumLeft;
  48.     
  49.     int32 maximumRight = Min( topRight.Sizer().MaximumWidth(),
  50.                                       bottomRight.Sizer().MaximumWidth() );
  51.     
  52.     Range32 leftRange( Max( 1ul, PaneSize().h - 1 - maximumRight ),
  53.                              PaneSize().h - 1 - minimumRight );
  54.  
  55.     return Max( topLeft.Sizer().BestWidth( leftRange ),
  56.                     bottomLeft.Sizer().BestWidth( leftRange ) );
  57.   }
  58.  
  59. int32 RuledFourSquareTiling::VerticalSplitPosition() const
  60.   {
  61.     int32 minimumTop = Max( topLeft.Sizer().MinimumHeight(),
  62.                                     topRight.Sizer().MinimumHeight() );
  63.     
  64.     if ( minimumTop >= PaneSize().v )
  65.         return PaneSize().v;
  66.     
  67.     int32 minimumBottom = Max( bottomLeft.Sizer().MinimumHeight(),
  68.                                         bottomRight.Sizer().MinimumHeight() );
  69.     
  70.     if ( minimumBottom >= PaneSize().v - 1 - minimumTop )
  71.         return minimumTop;
  72.     
  73.     int32 maximumBottom = Min( bottomLeft.Sizer().MaximumHeight(),
  74.                                         bottomRight.Sizer().MaximumHeight() );
  75.     
  76.     Range32 topRange( Max( 1ul, PaneSize().v - 1 - maximumBottom ),
  77.                             PaneSize().v - 1 - minimumBottom );
  78.     
  79.     return Max( topLeft.Sizer().BestHeight( topRange ),
  80.                     topRight.Sizer().BestHeight( topRange ) );
  81.   }
  82.  
  83. void RuledFourSquareTiling::PaneSizeChanged()
  84.   {
  85.     Point32 oldSize = bottomRight.Bounds().BottomRight();
  86.     
  87.     Rectangle32 keyPixel;
  88.     keyPixel.left   = HorizontalSplitPosition();
  89.     keyPixel.top    = VerticalSplitPosition();
  90.     keyPixel.right  = Min( keyPixel.left + 1ul, PaneSize().h );
  91.     keyPixel.bottom = Min( keyPixel.top + 1ul, PaneSize().v );
  92.     
  93.     topLeft.proposedBounds =     Rectangle32( 0,                        0,
  94.                                                             keyPixel.left,        keyPixel.top );
  95.  
  96.     topRight.proposedBounds =    Rectangle32( keyPixel.right,    0,
  97.                                                             PaneSize().h,        keyPixel.top );
  98.  
  99.     bottomLeft.proposedBounds =  Rectangle32( 0,                        keyPixel.bottom,
  100.                                                             keyPixel.left,        PaneSize().v );
  101.  
  102.     bottomRight.proposedBounds = Rectangle32( keyPixel.right,    keyPixel.bottom,
  103.                                                             PaneSize().h,        PaneSize().v );
  104.  
  105.     horizontalLine.proposedBounds = Rectangle32( 0,                        keyPixel.top,
  106.                                                                 PaneSize().h,        keyPixel.bottom );
  107.     
  108.     upperVerticalLine.proposedBounds = Rectangle32(    keyPixel.left,        0,
  109.                                                                     keyPixel.right,    keyPixel.top );
  110.  
  111.     lowerVerticalLine.proposedBounds = Rectangle32(    keyPixel.left,        keyPixel.bottom,
  112.                                                                     keyPixel.right,    PaneSize().v );
  113.     
  114.     TiledPane *shuffleFirst = 0;
  115.     
  116.     if ( PaneSize().h < oldSize.h )
  117.         if ( PaneSize().v < oldSize.v )
  118.           {
  119.                                     shuffleFirst = &topLeft;
  120.             topLeft                .shuffleNext = &upperVerticalLine;
  121.             upperVerticalLine    .shuffleNext = &topRight;
  122.             topRight                .shuffleNext = &horizontalLine;
  123.             horizontalLine        .shuffleNext = &bottomLeft;
  124.             bottomLeft            .shuffleNext = &lowerVerticalLine;
  125.             lowerVerticalLine    .shuffleNext = &bottomRight;
  126.             bottomRight            .shuffleNext = 0;
  127.           }
  128.          else
  129.           {
  130.                                     shuffleFirst = &bottomLeft;
  131.             bottomLeft            .shuffleNext = &lowerVerticalLine;
  132.             lowerVerticalLine    .shuffleNext = &bottomRight;
  133.             bottomRight            .shuffleNext = &horizontalLine;
  134.             horizontalLine        .shuffleNext = &topLeft;
  135.             topLeft                .shuffleNext = &upperVerticalLine;
  136.             upperVerticalLine    .shuffleNext = &topRight;
  137.             topRight                .shuffleNext = 0;
  138.           }
  139.      else
  140.         if ( PaneSize().v < oldSize.v )
  141.           {
  142.                                     shuffleFirst = &topRight;
  143.             topRight                .shuffleNext = &upperVerticalLine;
  144.             upperVerticalLine    .shuffleNext = &topLeft;
  145.             topLeft                .shuffleNext = &horizontalLine;
  146.             horizontalLine        .shuffleNext = &bottomRight;
  147.             bottomRight            .shuffleNext = &lowerVerticalLine;
  148.             lowerVerticalLine    .shuffleNext = &bottomLeft;
  149.             bottomLeft            .shuffleNext = 0;
  150.           }
  151.          else
  152.           {
  153.                                     shuffleFirst = &bottomRight;
  154.             bottomRight            .shuffleNext = &lowerVerticalLine;
  155.             lowerVerticalLine    .shuffleNext = &bottomLeft;
  156.             bottomLeft            .shuffleNext = &horizontalLine;
  157.             horizontalLine        .shuffleNext = &topRight;
  158.             topRight                .shuffleNext = &upperVerticalLine;
  159.             upperVerticalLine    .shuffleNext = &topLeft;
  160.             topLeft                .shuffleNext = 0;
  161.           }
  162.     
  163.     ShufflePanes( shuffleFirst );
  164.   }
  165.  
  166. int32 RuledFourSquareTiling::MinimumWidth() const
  167.   {
  168.     return TileSum( Max( topLeft.Sizer().MinimumWidth(),    bottomLeft.Sizer().MinimumWidth() ),
  169.                          Max( topRight.Sizer().MinimumWidth(),   bottomRight.Sizer().MinimumWidth() ) );
  170.   }
  171.  
  172. int32 RuledFourSquareTiling::MinimumHeight() const
  173.   {
  174.     return TileSum( Max( topLeft.Sizer().MinimumHeight(),    topRight.Sizer().MinimumHeight() ),
  175.                          Max( bottomLeft.Sizer().MinimumHeight(), bottomRight.Sizer().MinimumHeight() ) );
  176.   }
  177.  
  178. int32 RuledFourSquareTiling::MaximumWidth() const
  179.   {
  180.     return TileSum( Min( topLeft.Sizer().MaximumWidth(),    bottomLeft.Sizer().MaximumWidth() ),
  181.                          Min( topRight.Sizer().MaximumWidth(),   bottomRight.Sizer().MaximumWidth() ) );
  182.   }
  183.  
  184. int32 RuledFourSquareTiling::MaximumHeight() const
  185.   {
  186.     return TileSum( Min( topLeft.Sizer().MaximumHeight(),    topRight.Sizer().MaximumHeight() ),
  187.                          Min( bottomLeft.Sizer().MaximumHeight(), bottomRight.Sizer().MaximumHeight() ) );
  188.   }
  189.  
  190. int32 RuledFourSquareTiling::ReasonableWidth() const
  191.   {
  192.     return TileSum( Max( topLeft.Sizer().ReasonableWidth(),    bottomLeft.Sizer().ReasonableWidth() ),
  193.                          Max( topRight.Sizer().ReasonableWidth(),   bottomRight.Sizer().ReasonableWidth() ) );
  194.   }
  195.  
  196. int32 RuledFourSquareTiling::ReasonableHeight() const
  197.   {
  198.     return TileSum( Max( topLeft.Sizer().ReasonableHeight(),    topRight.Sizer().ReasonableHeight() ),
  199.                          Max( bottomLeft.Sizer().ReasonableHeight(), bottomRight.Sizer().ReasonableHeight() ) );
  200.   }
  201.  
  202. int32 RuledFourSquareTiling::BestWidth( Range32 bounds ) const
  203.   {
  204.     int32 minimumRight = TileSum( 0, Max( topRight.Sizer().MinimumWidth(), bottomRight.Sizer().MinimumWidth() ) );
  205.  
  206.     if ( minimumRight >= bounds.End() )
  207.         return bounds.End();
  208.     
  209.     Range32 leftBounds( Max( 0L, bounds.Start() - minimumRight ), bounds.End() - minimumRight );
  210.     
  211.     int32 left = TileSum( Max( topLeft.Sizer().BestWidth( leftBounds ), bottomLeft.Sizer().BestWidth( leftBounds ) ), 0 );
  212.  
  213.     if ( left >= bounds.End() - minimumRight )
  214.         return bounds.End();
  215.     
  216.     Range32 rightBounds( Max( 0L, bounds.Start() - left ), bounds.End() - left );
  217.     
  218.     return left + Max( topRight.Sizer().BestWidth( rightBounds ), bottomRight.Sizer().BestWidth( rightBounds ) );
  219.   }
  220.  
  221. int32 RuledFourSquareTiling::BestHeight( Range32 bounds ) const
  222.   {
  223.     int32 minimumBottom = TileSum( 0, Max( bottomLeft.Sizer().MinimumHeight(), bottomRight.Sizer().MinimumHeight() ) );
  224.  
  225.     if ( minimumBottom >= bounds.End() )
  226.         return bounds.End();
  227.     
  228.     Range32 topBounds( Max( 0L, bounds.Start() - minimumBottom ), bounds.End() - minimumBottom );
  229.     
  230.     int32 top = TileSum( Max( topLeft.Sizer().BestHeight( topBounds ), topRight.Sizer().BestHeight( topBounds ) ), 0 );
  231.  
  232.     if ( top >= bounds.End() - minimumBottom )
  233.         return bounds.End();
  234.     
  235.     Range32 bottomBounds( Max( 0L, bounds.Start() - top ), bounds.End() - top );
  236.     
  237.     return top + Max( bottomLeft.Sizer().BestHeight( bottomBounds ), bottomRight.Sizer().BestHeight( bottomBounds ) );
  238.   }
  239.